using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Permissions;
using System.Threading;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;

using Caliburn.Micro;

using Haushaltsbuch.Domain.Authentication;
using Haushaltsbuch.Events;
using Haushaltsbuch.Helpers;
using Haushaltsbuch.ViewModels.Interfaces;
using Haushaltsbuch.ViewModels.Options;

namespace Haushaltsbuch.ViewModels
{
    [Export(typeof(IShell))]
    public class ShellViewModel : Conductor<IShellContent>, IShell,
                                  IHandle<ViewChangeEvent>, IHandle<MessageToUserEvent>, IHandle<CloseWindowEvent>, IHandle<CurrentUserChangedEvent>
    {
        private readonly IBlankViewModel blank;
        private readonly IEditUsersViewModel editUsersView;
        private readonly IEventAggregator events;
        private readonly DispatcherTimer timer;
        private SolidColorBrush messageColor;
        private string messageForUser;
        public ILoginViewModel LoginView { get; set; }
 

        public SolidColorBrush MessageColor
        {
            get { return this.messageColor; }
            set
            {
                if (Equals(value, this.messageColor)) return;
                this.messageColor = value;
                this.NotifyOfPropertyChange(() => this.MessageColor);
            }
        }

        public string Username
        {
            get
            {
                if (Thread.CurrentPrincipal.Identity.GetType() != typeof(HaushaltsbuchIdentity))
                    return string.Empty;

                var currentIdentity = (HaushaltsbuchIdentity) Thread.CurrentPrincipal.Identity;
                if (currentIdentity.IsAuthenticated)
                    return "Angemeldet als " + currentIdentity.Fullname;

                return string.Empty;
            }
        }

        public string MessageForUser
        {
            get { return this.messageForUser; }
            set
            {
                this.messageForUser = value;
                this.NotifyOfPropertyChange(() => this.MessageForUser);
            }
        }

        public ShellViewModel(ILoginViewModel loginView, IBlankViewModel blank, IEditUsersViewModel editUsersView,
                              IEventAggregator events)
        {
            this.LoginView = loginView;
            this.ActivateItem(this.LoginView);
            this.timer = new DispatcherTimer();

            this.timer.Tick += this.timer_Tick;
            this.blank = blank;
            this.editUsersView = editUsersView;
            this.events = events;
            events.Subscribe(this);

            
        }

        #region MenuItems

        public bool CanEditUsers
        {
            get { return true; }
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Admin")]
        public void EditUsers()
        {
            this.ActivateItem(this.editUsersView);
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Admin")]
        public void EditShops()
        {
            //this.ActivateItem(new EditShopsViewModel(this.events));
        }

        public void Exit()
        {
            this.TryClose();
        }

        public void Logout()
        {
            HaushaltsbuchPrincipal.Logout();
            this.ActivateItem(this.LoginView);
            this.events.Publish(new CurrentUserChangedEvent());
        }

        #endregion

        private void timer_Tick(object sender, EventArgs e)
        {
            this.MessageForUser = "";
            this.timer.Stop();
        }

        #region IHandle<CloseWindowEvent> Members

        public void Handle(CloseWindowEvent message)
        {
            (this.GetView() as Window).Close();
        }

        #endregion

        #region IHandle<MessageToUserEvent> Members

        public void Handle(MessageToUserEvent message)
        {
            switch (message.Type)
            {
                case MessageType.Normal:
                    this.MessageColor = new SolidColorBrush(Colors.Black);
                    this.MessageForUser = message.Message;
                    break;
                case MessageType.Warning:
                    this.MessageColor = new SolidColorBrush(Colors.Orange);
                    this.MessageForUser = "Warning: " + message.Message;
                    break;
                case MessageType.Error:
                    this.MessageColor = new SolidColorBrush(Colors.Red);
                    this.MessageForUser = "Error: " + message.Message;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            this.timer.Interval = new TimeSpan(0, 0, message.Duration);
            this.timer.Start();
        }

        #endregion

        #region IHandle<ViewChangeEvent> Members

        public void Handle(ViewChangeEvent message)
        {
            if (string.IsNullOrEmpty(message.ViewName))
            {
                this.ActivateItem(message.View);
                return;
            }
            switch (message.ViewName)
            {
                case "blank":
                    this.ActivateItem(this.blank);
                    break;

                case "editUsers":
                    this.ActivateItem(this.editUsersView);
                    break;
            }
        }

        #endregion

        public void Handle(CurrentUserChangedEvent message)
        {
            this.NotifyOfPropertyChange(() => this.Username);
        }

        public void DisplayFatalException(Exception error)
        {
            WindowManager window = new WindowManager();
            window.ShowPopup(new ExeptionViewModel(error));

        }
    }
}